package com.citcc.api.netty.xc.xcserver;


import com.citcc.api.controller.PayController;
import com.citcc.api.controller.PayNotifyController;
import com.citcc.api.netty.EchargeConstants;
import com.citcc.api.netty.bean.ConsuMessage;
import com.citcc.api.netty.server.ChannelMap;
import com.citcc.api.netty.server.TerminalAddressMap;
import com.citcc.api.netty.utils.BitUtil;
import com.citcc.api.netty.utils.HexUtil;
import com.citcc.api.netty.utils.XcUtil;
import com.citcc.business.bean.CdzAppUser;
import com.citcc.business.bean.CdzChargingEntity;
import com.citcc.business.bean.CdzGun;
import com.citcc.business.bean.CdzIndent;
import com.citcc.business.bean.CdzOrderRefundEntity;
import com.citcc.business.bean.CdzOrderRefundEntityExample;
import com.citcc.business.bean.CdzRates;
import com.citcc.business.bean.CdzStake;
import com.citcc.business.bean.CdzStation;
import com.citcc.business.bean.CdzWarn;
import com.citcc.business.bean.PayResult;
import com.citcc.business.bean.UserOrderEntity;
import com.citcc.business.bean.UserOrderEntityExample;
import com.citcc.business.service.CdzAmountDetailService;
import com.citcc.business.service.CdzAppUserService;
import com.citcc.business.service.CdzChargingService;
import com.citcc.business.service.CdzGunService;
import com.citcc.business.service.CdzIndentService;
import com.citcc.business.service.CdzOrderRefundService;
import com.citcc.business.service.CdzRatesService;
import com.citcc.business.service.CdzStakeService;
import com.citcc.business.service.CdzStationService;
import com.citcc.business.service.CdzWarnService;
import com.citcc.business.service.ScanCodeService;
import com.citcc.business.util.CollectionUtil;
import com.citcc.business.util.IdGenerator;
import com.citcc.common.jpush.PushUtil;
import com.github.pagehelper.util.StringUtil;

import java.math.BigDecimal;
import java.net.InetSocketAddress;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author liyachong
 * @date 2019/5/28
 * @time 15:41
 */

/**
 * 程序可以接收下级平台发送的业务报文，并转换成POJO对象。
 *数据流：下级平台-->LoggingHandler-->Decoder-->Message-->BusiHandler-->Message-->Encoder-->LoggingHandler-->下级平台。
 */
@SuppressWarnings("all")
public class XcServerHandler extends SimpleChannelHandler {
    private Logger log = LoggerFactory.getLogger(XcServerHandler.class);
    
    //处理充电桩业务
    public static CdzStakeService cdzStakeService;
    
    //处理充电枪业务
    public static CdzGunService cdzGunService;
    
    //订单业务
    public static CdzIndentService cdzIndentService;
    
    public static CdzAppUserService cdzAppUserService;
    
    // 扩展
 	public static ScanCodeService scanCodeService;
 	
    // 充电信息
  	public static CdzChargingService cdzChargingService;
  	
    // 警告信息
   	public static CdzWarnService cdzWarnService;
   	
    // 桩信息
   	public static CdzStationService cdzStationService;
   	
    // 费率信息
   	public static CdzRatesService cdzRatesService;
   	
   	public static PayNotifyController payNotifyController;
   	
   	public static CdzOrderRefundService cdzOrderRefundService;
   	
   	public static CdzAmountDetailService cdzAmountDetailService;

    
    private static String charging_status = "0";//充电中
    private static String not_charging_status = "1";//未充电
    private static String finish_charging_status = "2";//已完成
    
    
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        ConsuMessage msg = (ConsuMessage) e.getMessage();
        ChannelBuffer body = msg.getMsgBody();
        InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        if(StringUtils.isBlank(msg.getMsgId()+"")){
        	return;
        }
        switch (msg.getMsgId()) {
            case 0x01://登录
            	log.info("xc接收到客户端登录请求地址:"+req);
            	StringBuffer sb1 = new StringBuffer();
                StringBuffer sb2 = new StringBuffer();
                for(int i = 0;i<16;i++){
                	sb1.append(Integer.toHexString(body.readUnsignedByte()));
                }
                for(int i = 0;i<16;i++){
                	sb2.append(Integer.toHexString(body.readUnsignedByte()));
                }
                //转10进制字符串
            	String terminalNo = XcUtil.convertHexToString(sb1.toString());
            	
                //转10进制字符串
            	String xlh = XcUtil.convertHexToString(sb2.toString());
            	int type = body.readUnsignedByte();
            	int num = body.readUnsignedByte();
            	int version = body.readUnsignedByte();
            	body.readBytes(16);//程序版本
            	long j = body.readUnsignedInt();
            	long w = body.readUnsignedInt();
            	log.info("桩类型:"+type+"-->"+(type==0 ? "直流桩" :"交流桩")+"-->枪数量:"+num+"-->版本:"+version+"-->经度:"+((double)j/1000000)+"-->维度:"+((double)w/1000000));
            	log.info("序列号===="+xlh);
                log.info("XC服务端接收到数据[{}]",msg.toString());
                log.info("XC服务端接收到命令0x"+Integer.toHexString(msg.getMsgId())+"-->终端号:"+terminalNo);
            	log.info("xc接收到客户端登录请求时:-终端号号:"+terminalNo);
            	CdzStake cdzs = cdzStakeService.getCdzStakeByStakeCode(terminalNo);
                if(cdzs!=null){
                	long s = System.currentTimeMillis();
                	//放入map
                    ChannelMap.addChannel(terminalNo, e.getChannel());
                    TerminalAddressMap.addAddress(req,terminalNo);// key:地址    value:桩号
                    xcResponseLogin(terminalNo,msg,ctx,e, EchargeConstants.XC_LOGIN_SUCCESS_C);
                    log.info("xc终端号==============="+terminalNo+"-->登录成功"+"----链接状态:"+e.getChannel().isConnected()+"-->开启状态:"+e.getChannel().isOpen()+"-->耗时:"+(System.currentTimeMillis()-s));
                    
                    log.info("充电桩在线channel数量="+ChannelMap.getNum());
                }else{
                	log.info("xc设备号==============="+terminalNo+"-->不存在登录失败");
                    //响应登录失败
                    xcResponseLogin(terminalNo,msg,ctx,e,EchargeConstants.XC_LOGIN_FAIL_C1);//不存在设备号
                }
                break;
            case 0x03:
            	//心跳请求接收和响应
                xcResponseHeart(msg,ctx,e);
                break;
            case 0x43:
            	//启动命令的响应
                receiveStartResp(msg,ctx,e);
                break;
            case 0x45:
            	//停止充电命令的响应
                receiveStopResp(msg,ctx,e);
                break;
            case 0x11:
            	//客户端实时数据的接收处理和响应
                xcHandleRealTimeData(msg,ctx,e);
                break;
            case 0x47:
            	//客户端历史数据的接收处理和响应
                xcHandleHistoryData(msg,ctx,e,EchargeConstants.XC_UPLOAD_HISTORY_C);
                break;
            case 0x13:
            	//客户端告警信息数据的接收处理和响应
                xcHandleWarnData(msg,ctx,e);
                break;
            case 0x05:
            	//浮点费率
                xcFl(msg,ctx,e,EchargeConstants.XC_UPLOAD_FL__C);
                break;
            case 0x75:
            	//对时
                xcCheckTime(msg,ctx,e);
                break;
            default:
                break;
        }
    }
    
    @Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		super.exceptionCaught(ctx, e);
		if(!e.getChannel().isConnected() && !e.getChannel().isOpen()){
			e.getChannel().close();
		}
        log.warn("=======exceptionCaught=======");
	}

	//封装登录响应数据体
    private void xcResponseLogin(String terminalNo,ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e,int c) {
        ChannelBuffer bodyBuffer = ChannelBuffers.buffer(32);
        bodyBuffer.writeShort(0x001E);//帧长度
        bodyBuffer.writeShort(0xFFE1);//帧长度取反
        bodyBuffer.writeByte(msg.getNo());//序列号
        bodyBuffer.writeByte(msg.getDataObj());//数据对象
        bodyBuffer.writeByte(0x02);//登录响应命令
        bodyBuffer.writeByte(c);//登录成功还是失败
        bodyBuffer.writeBytes(HexUtil.hexStringToByte(XcUtil.convertStringToHex(terminalNo)));//终端号
        //TODO 时间处理
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int day = cal.get(Calendar.DATE);
        int month = cal.get(Calendar.MONTH) + 1;
        int year = cal.get(Calendar.YEAR);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int second = cal.get(Calendar.SECOND);
        int millisecond = cal.get(Calendar.MILLISECOND);
       /* System.out.println("天==="+cal.get(Calendar.DATE));
        System.out.println("月==="+(cal.get(Calendar.MONTH) + 1));
        System.out.println("年===="+cal.get(Calendar.YEAR));
        //时分秒
        System.out.println("时==="+cal.get(Calendar.HOUR_OF_DAY));
        System.out.println("分==="+cal.get(Calendar.MINUTE));
        System.out.println("秒==="+cal.get(Calendar.SECOND));
        System.out.println("毫秒==="+cal.get(Calendar.MILLISECOND));*/
        bodyBuffer.writeShort(millisecond);
        bodyBuffer.writeByte(second);
        bodyBuffer.writeByte(minute);
        bodyBuffer.writeByte(hour);
        bodyBuffer.writeByte(day);
        bodyBuffer.writeByte(month);
        bodyBuffer.writeByte(year-2000);
        
        msg.setMsgBody(bodyBuffer);

        e.getChannel().write(msg);

    }
    
    //封装退出响应数据体
    /*private void responseLogout(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e,int c) {
        ChannelBuffer bodyBuffer = ChannelBuffers.buffer(14);
        bodyBuffer.writeShort(0x1500);//长度
        bodyBuffer.writeBytes(HexUtil.hexStringToByte(Long.toHexString(msg.getDeviceNo())));//终端号
        bodyBuffer.writeByte(msg.getMsgId());//退出命令
        int s = msg.getSource();
        int qh = s-16;
        String frame = Integer.toHexString(s);
        if ("10".equals(frame)) {
            bodyBuffer.writeByte(0x00);//1帧来源+枪号
        }else if("11".equals(frame)) {
            bodyBuffer.writeByte(0x01);//1帧来源+枪号
        }else if("12".equals(frame)) {
            bodyBuffer.writeByte(0x02);//1帧来源+枪号
        }else if("13".equals(frame)) {
            bodyBuffer.writeByte(0x03);//1帧来源+枪号
        }

        bodyBuffer.writeByte(0x01);//应答  0.请求帧，1.应答帧，2.主动上传
        bodyBuffer.writeByte(c);//1.确认
        bodyBuffer.writeInt(0x01070502);//版本
        msg.setMsgBody(bodyBuffer);

        e.getChannel().write(msg);
        log.info("响应客户端的退出请求-----------");

    }*/



    //封装心跳响应数据体
    private void xcResponseHeart(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e) {
        ChannelBuffer body = msg.getMsgBody();
        int state = body.readUnsignedByte();
        int wd = body.readUnsignedByte();
    	//TODO  判断是否存在该终端号  
    	InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
        log.info("xc接收到客户端发送的心跳请求地址:"+req+"-->对应的终端号:"+terminalNo+"-->充电桩状态:"+state+"-->温度:"+wd);
    	Channel channel = ChannelMap.getChannelByName(terminalNo);
    	if(channel!=null){
    		log.warn("xc从map中获取到终端号:"+terminalNo+"--------->连接状态:"+channel.isConnected()+"-->开启状态:"+channel.isOpen());
    	}
    	Channel chanel = e.getChannel();
    	if(chanel!=null){
    		ChannelMap.addChannel(terminalNo, chanel);
    		TerminalAddressMap.addAddress(req, terminalNo);
    		log.warn("xc终端号:"+terminalNo+"--------->连接状态:"+chanel.isConnected()+"-->开启状态:"+chanel.isOpen());
    	}else{
    		log.warn("xc终端号:"+terminalNo+"--------->chanel空");
    		e.getChannel().close();
    	}
        ChannelBuffer bodyBuffer = ChannelBuffers.buffer(8);
        bodyBuffer.writeShort(0x0006);//帧长度
        bodyBuffer.writeShort(0xFFF9);//帧长度取反
        bodyBuffer.writeByte(msg.getNo());//序号
        bodyBuffer.writeByte(msg.getDataObj());//数据对象
        bodyBuffer.writeByte(0x04);//心跳响应命令
        bodyBuffer.writeByte(0x00);//心跳回应帧
        
        msg.setMsgBody(bodyBuffer);
        ChannelFuture f = e.getChannel().write(msg);
        log.info("xc响应发送的心跳请求-终端号:"+terminalNo);
    }

    //处理客户端对开启指令的响应
    private void receiveStartResp(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e) {
        if(msg!=null && msg.getMsgBody()!=null && 
        		StringUtils.isNotBlank(msg.getDataObj()+"")){
            ChannelBuffer body = msg.getMsgBody();
            int qh = msg.getDataObj();//已转成10进制
            InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
            int port = address.getPort(); //得到的是客户端绑定的port
            String add = address.getAddress().toString();
            String req = add+":"+port;
            String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
            log.info("xc接收到客户端对开启充电指令的响应地址:"+req+"-->对应的终端号:"+terminalNo+"-->枪号:"+qh);
            if(msg.getMsgId() == EchargeConstants.XC_START_RESPONSE_C){//0x43
                int state = body.readUnsignedByte();
                if(state == EchargeConstants.XC_START_RESPONSE_C01){
                    //TODO 开启成功 
                    CdzGun cdzGun = new CdzGun();
                    cdzGun.setStakeCode(terminalNo);
                    cdzGun.setGunNum(qh+"");
                    cdzGun.setUpdateTime(new Date());
                    cdzGun.setStatus("0");//0 充电中
                    boolean res  = cdzGunService.updateStatus(cdzGun);
                    if(res){
                    	log.info("终端号:"+terminalNo+"-->枪号:"+qh+"------------启动充电成功");
                    	//更新订单状态为   0开始充电
                    	UserOrderEntity entity = new UserOrderEntity();
                    	entity.setStakeCode(terminalNo+"");
                    	entity.setGunCode(qh+"");
                    	entity.setUpdateTime(new Date());
                    	entity.setChargeState(charging_status);//订单表  充电中
                    	UserOrderEntityExample example = new UserOrderEntityExample();
                    	UserOrderEntityExample.Criteria criteria = example.createCriteria();
                    	criteria.andDelFlagEqualTo("0");
                    	criteria.andChargeStateEqualTo(not_charging_status);//未充电  
                    	criteria.andStakeCodeEqualTo(terminalNo+"");
                    	criteria.andGunCodeEqualTo(qh+"");
                    	criteria.andPayStateEqualTo("1");//已冻结
                    	example.setOrderByClause("CREATE_TIME DESC");//查找最新的一条未充电的订单
                    	UserOrderEntity userEntity = scanCodeService.getUserOrderEntity(example);
                    	if(userEntity!=null){
                    		entity.setId(userEntity.getId());
                    		boolean r = scanCodeService.updateUserOrderEntityById(entity);
                    		if(r){
                        		//插入一条充电信息
                        		UserOrderEntityExample ex = new UserOrderEntityExample();
                            	UserOrderEntityExample.Criteria cr = ex.createCriteria();
                            	cr.andDelFlagEqualTo("0");
                            	cr.andChargeStateEqualTo(charging_status);//充电中
                            	cr.andStakeCodeEqualTo(terminalNo);
                            	cr.andGunCodeEqualTo(qh+"");
                            	cr.andPayStateEqualTo("1");//已冻结
                            	ex.setOrderByClause("CREATE_TIME DESC");
                            	UserOrderEntity e1 = scanCodeService.getUserOrderEntity(ex);
                            	if(e1!=null){
                            		CdzChargingEntity cdzChargingEntity = new CdzChargingEntity();
                            		cdzChargingEntity.setId(e1.getId());
                            		cdzChargingEntity.setDelFlag("0");
                            		cdzChargingEntity.setSoc("0");
                            		cdzChargingEntity.setStakeCode(terminalNo);
                            		cdzChargingEntity.setGunNum(qh+"");
                            		cdzChargingEntity.setDl("0");
                            		cdzChargingEntity.setDl("0");
                            		cdzChargingEntity.setDy("0");
                            		cdzChargingEntity.setDn("0");
                            		cdzChargingEntity.setTime("0");
                            		cdzChargingEntity.setSyTime("0");
                            		cdzChargingService.insertCdzChargingEntity(cdzChargingEntity);
                            		log.info("-----插入充电信息--------------");
                            		//推送消息到app
                                    CdzAppUser user = cdzAppUserService.selectByPrimaryKey(e1.getUserId());
                                    List<Object> registrationIdList = new ArrayList<>();
                                    if (StringUtils.isNotEmpty(user.getDeviceId())) {
                                        registrationIdList.add(user.getDeviceId());
                                        String title = "充电状态改变";
                                        String b = "推送消息到app";
                                        log.info("手机号:"+e1.getUserPhone()+"-->设备id:"+user.getDeviceId()+"标题:"+title);
                                        try {
                                            PushUtil.messagePush(registrationIdList, title, b, "1", "", user.getType());
                                        } catch (Exception e2) {
                                            e2.printStackTrace();
                                        }
                                    }
                            	}
                        	}
                    	}
                    	
                    	
                    	//充电中的订单  获取deviceId
                    	//String deviceId = deviceId(deviceNo+"",qh+"",charging_status);
                    }
                }else if(state == EchargeConstants.START_FAIL_C){
                    log.info("xc------------------启动充电失败,充电状态仍是未充电");
                }
            }else{
                log.error("xc------------------未接受到客户端的响应信息");
            }
        }

    }
    
    //处理客户端对关闭充电指令的响应
    private void receiveStopResp(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e) {
        if(msg!=null && msg.getMsgBody()!=null && 
        		StringUtils.isNotBlank(msg.getDataObj()+"")){
            ChannelBuffer body = msg.getMsgBody();
            int qh = msg.getDataObj();//已转成10进制
            InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
            int port = address.getPort(); //得到的是客户端绑定的port
            String add = address.getAddress().toString();
            String req = add+":"+port;
            String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
            log.info("xc接收到客户端对关闭充电指令的响应地址:"+req+"-->对应的终端号:"+terminalNo+"-->枪号:"+qh);
            if(msg.getMsgId() == EchargeConstants.XC_STOP_RESPONSE_C){//0x45
                int state = body.readUnsignedByte();
                if(state == 0){
                	log.info("xc终端号:"+terminalNo+"-->枪号:"+qh+"-->结束充电成功");
                }  
            }else{
                log.error("xc------------------未接受到客户端对关闭充电指令的响应信息");
            }
        }

    }
    
    
    //处理客户端发送到监控平台的历史数据
    public void xcHandleHistoryData(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e,int c) throws Exception{
        ChannelBuffer bodyBuffer = msg.getMsgBody();
        int qh = msg.getDataObj();
        int no = msg.getNo();
        InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
        log.info("xc接收客户端发送的历史数据--终端号="+terminalNo+"-->枪号:"+qh+"-->序号:"+no);
        StringBuffer sb1 = new StringBuffer();
        StringBuffer sb2 = new StringBuffer();
        for(int i = 0;i<22;i++){
        	sb1.append(Integer.toHexString(bodyBuffer.readUnsignedByte()));
        }
        for(int i = 0;i<16;i++){
        	sb2.append(Integer.toHexString(bodyBuffer.readUnsignedByte()));
        }
        //转10进制字符串
    	String reqNo = XcUtil.convertHexToString(sb1.toString());
    	log.info("xc接收客户端发送的历史数据--终端号="+terminalNo+"-->枪号:"+qh+"-->交易流水号:"+reqNo);
        //转10进制字符串
    	String kh = XcUtil.convertHexToString(sb2.toString());
    	log.info("xc接收客户端发送的历史数据--终端号="+terminalNo+"-->枪号:"+qh+"-->卡号:"+kh);
        int cddl = bodyBuffer.readUnsignedShort();//充电电量  0.01kw
        double cddl2 = (double)cddl/100;
        long dfze = bodyBuffer.readUnsignedInt();//电费总额  元  0.01
        double dfze2 = (double)dfze/100;
        long fwfze = bodyBuffer.readUnsignedInt();//服务费总额  元  0.01
        double fwfze2 = (double)fwfze/100;
        double totalPrice = dfze2+fwfze2;
        log.info("xc接收客户端发送的历史数据--终端号="+terminalNo+"-->枪号:"+qh+"-->充电电量(kw):"+cddl2+"-->电费总额(元):"+dfze2+"-->服务费总额(元):"+fwfze2);
        
        int millisecond = bodyBuffer.readUnsignedShort();
        int second = bodyBuffer.readUnsignedByte();
        int minute = bodyBuffer.readUnsignedByte();
        int hour = bodyBuffer.readUnsignedByte();
        int day = bodyBuffer.readUnsignedByte();
        int month = bodyBuffer.readUnsignedByte();
        int year = bodyBuffer.readUnsignedByte();
        
        String ss = (year+2000)+"-"+month+"-"+day+" "+hour+":"+minute+":"+second;
        
        int emillisecond = bodyBuffer.readUnsignedShort();
        int esecond = bodyBuffer.readUnsignedByte();
        int eminute = bodyBuffer.readUnsignedByte();
        int ehour = bodyBuffer.readUnsignedByte();
        int eday = bodyBuffer.readUnsignedByte();
        int emonth = bodyBuffer.readUnsignedByte();
        int eyear = bodyBuffer.readUnsignedByte();
        
        String ee = (eyear+2000)+"-"+emonth+"-"+eday+" "+ehour+":"+eminute+":"+esecond;
        
        int soc = bodyBuffer.readUnsignedByte();
        int reason = bodyBuffer.readUnsignedByte();
        log.info("xc接收客户端发送的历史数据--终端号="+terminalNo+"-->枪号:"+qh+"-->充电开始时间:"+ss+"-->充电结束时间:"+ee+"-->当前soc:"+soc+"-->结束原因:"+reason);
        
        //修改订单结束时间等数据
    	UserOrderEntity entity = new UserOrderEntity();
    	entity.setUpdateTime(new Date());
    	Date startDate = parseDate(ss);
    	Date endDate = parseDate(ee);
    	long time = secondBetween(startDate,endDate);//计算充电时长
    	entity.setStartTime(startDate);
    	entity.setEndTime(endDate);
    	entity.setChargeDn(bl2(cddl2));
    	entity.setEndType(reason+"");
    	entity.setChargeLong(new BigDecimal(time));
    	entity.setChargeState("2");//已完成  只要有历史数据，充电状态都为已完成
    	entity.setPayNumberPlan(new BigDecimal(bl2(totalPrice)));
    	//TODO 结束方式和电能
    	String id = "";
    	UserOrderEntityExample example = new UserOrderEntityExample();
    	UserOrderEntityExample.Criteria criteria = example.createCriteria();
    	criteria.andDelFlagEqualTo("0");
    	criteria.andChargeStateIn(Arrays.asList("0","2","4"));//充电中,已完成
    	criteria.andStakeCodeEqualTo(terminalNo+"");
    	criteria.andGunCodeEqualTo(qh+"");
    	criteria.andPayStateEqualTo("1");//已冻结
    	criteria.andTradeNoEqualTo(reqNo);
    	example.setOrderByClause("CREATE_TIME DESC");
    	UserOrderEntity userEntity = scanCodeService.getUserOrderEntity(example);
    	if(userEntity!=null){
    		entity.setId(userEntity.getId());
    		boolean res = scanCodeService.updateUserOrderEntityById(entity);
    		if(res){
    			id = userEntity.getId();
    			log.info("xc接收客户端发送的历史数据时--终端号="+terminalNo+"-->枪号:"+qh+"-->更新订单的开始充电时间和结束充电时间成功");
    			
    		}
    	}
    	
        //封装历史数据回应指令
        ChannelBuffer body = ChannelBuffers.buffer(50);
        body.writeShort(0x0030);//帧长度
        body.writeShort(0xFFCF);//帧长度取反
        body.writeByte(msg.getNo());//序号
        body.writeByte(msg.getDataObj());//数据对象
        body.writeByte(0x48);//响应命令
        body.writeByte(0x00);//上传成功
        body.writeBytes(HexUtil.hexStringToByte(sb1.toString()));//流水号
        body.writeBytes(HexUtil.hexStringToByte(sb2.toString()));//卡号
        body.writeInt(0x00018C81);//结算后余额       0x00000000
        
        msg.setMsgBody(body);
        e.getChannel().write(msg);
        //TODO 
        log.info("xc历史数据响应成功-------终端号:"+terminalNo+"-->枪号:"+qh);
        
        log.info("xc充电完成的订单id:"+id);
        if(StringUtils.isNoneBlank(id)){
        	//TODO 调用方法
        	//cdzAmountDetailService.endChargeBusiness(id);
        }
        if(userEntity!=null){
        	//推送消息到app
            CdzAppUser user = cdzAppUserService.selectByPrimaryKey(userEntity.getUserId());
            List<Object> registrationIdList = new ArrayList<>();
            if (StringUtils.isNotEmpty(user.getDeviceId())) {
                registrationIdList.add(user.getDeviceId());
                String title = "充电状态改变";
                String bb = "推送消息到app";
                log.info("手机号:"+userEntity.getUserPhone()+"-->设备id:"+user.getDeviceId()+"标题:"+title);
                try {
                    PushUtil.messagePush(registrationIdList, title, bb, "1", "", user.getType());
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }  
        }
    }
    
    
    //处理客户端发送到监控平台的实时数据
    public void xcHandleRealTimeData(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e) {
    	int qh = msg.getDataObj();
    	int no = msg.getNo();
        ChannelBuffer bodyBuffer = msg.getMsgBody();
        //TODO  判断是否存在该终端号  
    	InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
        log.info("xc接收到客户端发送的实时数据，请求地址:"+req+"-->对应的终端号:"+terminalNo+"-->枪号:"+qh);
        
        long zcddl = bodyBuffer.readUnsignedInt();//总充电量  单位kw
        long zyxsj = bodyBuffer.readUnsignedInt();//总运行时间   单位分钟
        long zcdsj = bodyBuffer.readUnsignedInt();//总充电时间  单位分钟
        log.info("xc实时数据时-设备号:"+terminalNo+"-->枪号:"+qh+"-->总电量(kw):"+zcddl+"-->总运行时间(分):"+zyxsj+"-->总充电时间(分):"+zcdsj);
        int chargingState = bodyBuffer.readUnsignedByte();//充电状态
        int gunState = bodyBuffer.readUnsignedByte();//充电枪状态
        int cwState = bodyBuffer.readUnsignedByte();//车位状态
        int dsState = bodyBuffer.readUnsignedByte();//地锁状态
        int dyxq = bodyBuffer.readUnsignedShort();//BMS电压需求 0.1V   转double除以10
        String dyxq2 = (double)dyxq/10+"";
        int dlxq = bodyBuffer.readUnsignedShort();//BMS电流需求 0.1A
        String dlxq2 = (double)dlxq/10+"";
        log.info("xc实时数据时-设备号:"+terminalNo+"-->枪号:"+qh+"-->车位状态值:"+cwState+"-->对应车位状态"+(cwState==0?"车位空闲" : "车位占用")+"-->地锁状态值:"+dsState+"-->对应地锁状态:"+(dsState==0?"地锁打开":"地锁锁住")+"-->BMS电压需求:"+dyxq2+"-->BMS电流需求:"+dlxq2);
        int cdms = bodyBuffer.readUnsignedByte();//充电模式
        int cddy = bodyBuffer.readUnsignedShort();//充电电压  0.1V   转double除以10
        int cddl = bodyBuffer.readUnsignedShort();//充电电流
        String cddy2 = (double)cddy/10+"";
        String cddl2 = (double)cddl/10+"";
        log.info("xc实时数据时-设备号:"+terminalNo+"-->枪号:"+qh+"-->充电模式:"+cdms+"-->充电电压:"+cddy2+"-->充电电流:"+cddl2);
        long ycdl = bodyBuffer.readUnsignedInt();//已充电量 0.01kw
        double ycdl2 = (double)ycdl/100;
        int ycsj = bodyBuffer.readUnsignedShort();//已充时间   单位分钟     
        int gssysj = bodyBuffer.readUnsignedShort();//估算剩余时间   单位分钟   
        log.info("xc实时数据时-设备号:"+terminalNo+"-->枪号:"+qh+"-->已充电量(kw):"+ycdl2+"-->已充时间(分):"+ycsj+"-->预计充满剩余时间(分):"+gssysj);
        int soc = bodyBuffer.readUnsignedByte();//soc
        int zgdtdy = bodyBuffer.readUnsignedShort();//最高单体电压 0.1V
        int zgbh = bodyBuffer.readUnsignedByte();//编号
        int zddtdy = bodyBuffer.readUnsignedShort();//最低单体电压 0.1v
        int zdbh = bodyBuffer.readUnsignedByte();//编号
        int wd = bodyBuffer.readUnsignedByte();//温度
        int jcd = bodyBuffer.readUnsignedByte();//监测点
        long ycje = bodyBuffer.readUnsignedInt();//已充金额   单位元  保留两位
        double ycje2 = (double)ycje/100;
        log.info("xc实时数据时-设备号:"+terminalNo+"-->枪号:"+qh+"-->温度:"+wd+"-->监测点:"+jcd+"-->已充金额(元):"+ycje2);
        log.info("xc接收到客户端发送的实时数据时---设备号:"+terminalNo+"-->枪号:"+qh+"-->充电枪状态值:"+gunState+"-->对应状态:"+gunState(gunState)+"-->充电状态:"+chargingState+"-->对应状态值:"+chargState(chargingState)+"-->soc:"+soc);
        
       //枪状态      //0 枪已归位   1:未连接    2：已连接
       if(gunState==0 || gunState==1  || gunState==2){
        	log.info("xc接收到客户端发送的实时数据时---设备号:"+terminalNo+"-->枪号:"+qh+"-->充电枪状态值:"+gunState+"-->对应枪状态:"+gunState(gunState)+"-->充电状态:"+chargingState+"-->对应充电状态值:"+chargState(chargingState)+"-->开始更新枪的状态");
        	CdzGun gun = scanCodeService.checkCdzGun(qh+"", terminalNo);
        	if(gun!=null){
        		//当前枪的状态
        		String status = gun.getStatus();
        		CdzGun cdzGun = new CdzGun();
                cdzGun.setStakeCode(terminalNo);
                cdzGun.setGunNum(qh+"");
                cdzGun.setUpdateTime(new Date());
                if(gunState==0){
                	cdzGun.setStatus("2");//空闲
                }else if(gunState==2){//已连接
                	if(chargingState==0){
                		//待机中分几种情况
                		if("1".equals(status) || "4".equals(status)){//如果当前枪为已连接   未连接
                			cdzGun.setStatus("1");//已连接
                		}else if("0".equals(status)){//当前为充电中
                			cdzGun.setStatus("3");//已完成
                		}
                	}else if(chargingState==1){
                		cdzGun.setStatus("0");//充电中
                	}else if(chargingState==2){
                		cdzGun.setStatus("0");//充电中
                	}
                }
                else if(gunState==1){
                	cdzGun.setStatus("4");//未连接
                }else if(chargingState==3){//充电状态故障
                	cdzGun.setStatus("5");//故障
                }
                boolean res  = cdzGunService.updateStatus(cdzGun);
                if(res){
                	log.info("xc接收到客户端发送的实时数据时---设备号:"+terminalNo+"-->枪号:"+qh+"-->充电枪状态值:"+gunState+"-->对应枪状态:"+gunState(gunState)+"-->充电状态:"+chargingState+"-->对应充电状态值:"+chargState(chargingState)+"-->更新枪的状态成功");
                }
        	}
        	
        }
        if(chargingState==2 || chargingState==0){
        	//查询充电中的订单
        	UserOrderEntityExample example = new UserOrderEntityExample();
        	UserOrderEntityExample.Criteria criteria = example.createCriteria();
        	criteria.andDelFlagEqualTo("0");
        	criteria.andChargeStateIn(Arrays.asList("0","2","4"));//充电中,已完成
        	criteria.andStakeCodeEqualTo(terminalNo+"");
        	criteria.andGunCodeEqualTo(qh+"");
        	criteria.andPayStateEqualTo("1");//已冻结
        	example.setOrderByClause("CREATE_TIME DESC");
        	UserOrderEntity entity = scanCodeService.getUserOrderEntity(example);
        	if(entity!=null){
        		BigDecimal payNum = entity.getPayNumber();
        		if(payNum==null){
        			payNum = BigDecimal.ZERO;
        		}
        		BigDecimal syMoney = payNum.subtract(new BigDecimal(bl2(ycje2)));
        		if(syMoney.compareTo(BigDecimal.ZERO)<1){
        			syMoney = BigDecimal.ZERO;
        		}
        		//更新充电信息表
        		String id = entity.getId();
        		CdzChargingEntity charging = new CdzChargingEntity();
        		charging.setId(id);
        		charging.setSoc(soc+"");
        		charging.setUpdateTime(new Date());
        		charging.setDn(bl2(ycdl2));
        		charging.setDl(cddl2);
        		charging.setDy(cddy2);
        		charging.setTime(ycsj*60+"");//秒
        		charging.setUsingMoney(new BigDecimal(bl2(ycje2)));
        		charging.setFullTime(gssysj+"");//预计充满时间
        		charging.setSyMoney(syMoney);
        		int r = cdzChargingService.updateCdzChargingEntityById(charging);
        	}
        }
    }
    
    
    //处理客户端发送到监控平台的警告信息数据
    public void xcHandleWarnData(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e) {
        ChannelBuffer bodyBuffer = msg.getMsgBody();
        int qh = msg.getDataObj();
        //TODO  判断是否存在该终端号  
    	InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
        log.info("xc接收到客户端发送的告警数据，请求地址:"+req+"-->对应的终端号:"+terminalNo+"-->枪号:"+qh);
        //警告信息
        int w1 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "1", w1);
        
        int w2 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "2", w2);
        
        int w3 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "3", w3);
        
        int w4 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "4", w4);
        
        int w5 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "5", w5);
        
        int w6 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "6", w6);
        
        int w7 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "7", w7);
        
        int w8 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "8", w8);
        
        int w9 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "9", w9);
        
        int w10 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "10", w10);
        
        int w11 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "11", w11);
        
        int w12 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "12", w12);
        
        int w13 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "13", w13);
        
        int w14 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "14", w14);
        
        int w15 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "15", w15);
        
        int w16 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "16", w16);
        
        int w17 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "17", w17);
        
        int w18 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "18", w18);
        
        int w19 = bodyBuffer.readUnsignedByte();
        insertAndUpdate(terminalNo, qh, "19", w19);
        
    }
    
    //封装费率
    private void xcFl(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e,int c) {
    	//TODO  判断是否存在该终端号  
    	InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
        int no = msg.getNo();
        int dataObj = msg.getDataObj();
        ChannelBuffer body = msg.getMsgBody();
        int bit = body.readUnsignedByte();
        log.info("xc接收到客户端请求费率的地址:"+req+"-->对应的终端号:"+terminalNo+"-->请求序号:"+no+"-->是否为请求费率:"+bit);
    	//根据桩号查询站号，站号拿到rates值，查询费率
        String rates = "";
        CdzStake cdzStake = cdzStakeService.getCdzStakeByStakeCode(terminalNo);
        if(cdzStake!=null){
        	 CdzStation cdzStation = cdzStationService.getCdzStation(cdzStake.getStationId());
        	 if (null != cdzStation){
         	    rates = cdzStation.getRates();
             }
        }
    	float f = 1.5f;
    	if(StringUtil.isNotEmpty(rates)){
    		CdzRates rate = cdzRatesService.getCdzRates(rates);
    		if(rate!=null && rate.getDirectElectric()!=null){
    			BigDecimal serve = rate.getServe();
    			if(serve==null){
    				serve  = BigDecimal.ZERO;
    			}
    			f = rate.getDirectElectric().floatValue()+serve.floatValue();
    		}
    	}
    	int realF = (int)(f*100000);
    	realF = 59000;
    	String hex = Integer.toHexString(realF);
        String hex8 = HexUtil.befor0(hex, 8);
        
        log.info("xc设备号:"+terminalNo+"-->费率:"+f+"-->费率报文:"+hex8);
        ChannelBuffer bodyBuffer = ChannelBuffers.buffer(74);
        bodyBuffer.writeShort(0x0048);//帧长度
        bodyBuffer.writeShort(0xFFB7);//帧长度取反
        bodyBuffer.writeByte(msg.getNo());//序号
        bodyBuffer.writeByte(msg.getDataObj());//数据对象
        bodyBuffer.writeByte(0x06);//响应费率命令
        bodyBuffer.writeShort(0x0000);//尖服务费
        bodyBuffer.writeShort(0x0000);//峰服务费
        bodyBuffer.writeShort(0x0000);//平服务费
        bodyBuffer.writeShort(0x0000);//谷服务费
        bodyBuffer.writeBytes(HexUtil.hexStringToByte(hex8));//尖电价
        bodyBuffer.writeBytes(HexUtil.hexStringToByte(hex8));//峰电价
        bodyBuffer.writeBytes(HexUtil.hexStringToByte(hex8));//平电价
        bodyBuffer.writeBytes(HexUtil.hexStringToByte(hex8));//谷电价
        bodyBuffer.writeByte(0x0e);//14段
        bodyBuffer.writeShort(0x0078);//第1阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第2阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第3阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第4阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第5阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第6阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第7阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第8阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第9阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x0078);//第10阶段   120分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x003c);//第11阶段   60分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x003c);//第12阶段   60分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x003c);//第13阶段   60分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        bodyBuffer.writeShort(0x003c);//第14阶段   60分钟
        bodyBuffer.writeByte(0x01);//标志尖时段
        
        msg.setMsgBody(bodyBuffer);

        e.getChannel().write(msg);
        log.info("xc响应客户端的费率请求-----------终端号:"+terminalNo);

    }
    //接收终端对时请求的响应
    private void xcCheckTime(ConsuMessage msg, ChannelHandlerContext ctx, MessageEvent e) {
    	//TODO  判断是否存在该终端号  
    	InetSocketAddress address = (InetSocketAddress)ctx.getChannel().getRemoteAddress();
        int port = address.getPort(); //得到的是客户端绑定的port
        String add = address.getAddress().toString();
        String req = add+":"+port;
        String terminalNo = TerminalAddressMap.getTerminalNoByAdd(req);
        int no = msg.getNo();
        int dataObj = msg.getDataObj();
        ChannelBuffer body = msg.getMsgBody();
        int millisecond = body.readUnsignedShort();
        int second = body.readUnsignedByte();
        int minute = body.readUnsignedByte();
        int hour = body.readUnsignedByte();
        int day = body.readUnsignedByte();
        int month = body.readUnsignedByte();
        int year = body.readUnsignedByte();
        log.info("xc接收到客户端对时命令的响应:"+req+"-->对应的终端号:"+terminalNo+"-->请求序号:"+no+"--时间报文:"+(year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second+":"+millisecond));
    }
    
    
    public String deviceId(String deviceNo,String qh,String status){
    	String deviceId = "";
    	String phone = "";
    	UserOrderEntityExample example = new UserOrderEntityExample();
    	UserOrderEntityExample.Criteria criteria = example.createCriteria();
    	criteria.andDelFlagEqualTo("0");
    	criteria.andChargeStandardEqualTo(status);
    	criteria.andStakeCodeEqualTo(deviceNo+"");
    	criteria.andGunCodeEqualTo(qh+"");
    	criteria.andPayStateEqualTo("1");//已冻结
    	example.setOrderByClause("CREATE_TIME DESC");
    	UserOrderEntity e = scanCodeService.getUserOrderEntity(example);
		if(e!=null){
			phone = e.getUserPhone();
			if(StringUtils.isNotBlank(phone)){
				CdzAppUser user = cdzAppUserService.getAppUserByPhone(phone);
				if(user!=null){
					deviceId = user.getDeviceId();
					log.info("手机号="+phone+"-->对应的设备id=="+deviceId);
				}
			}
		}
    	return deviceId;
    }
    
   public String befor(String s){
    	StringBuffer buffer = new StringBuffer();
		if(s.length()==1){
			buffer.append("000");
			buffer.append(s);
		}else if(s.length()==2){
			buffer.append("00");
			buffer.append(s);
		}else if(s.length()==3){
			buffer.append("0");
			buffer.append(s);
		}else if(s.length()==0){
			buffer.append("0000");
		}
		
		return  buffer.toString();
		
	}
   
   

	//充电状态（0:充电中 1:未充电 2:已完成,3:关闭,4结束中） 订单表
	//0:待机   1启动充电 2：充电中  3：禁止充电
    //转化充电状态
	public  int convChargState(int state){
		if(state==0){//待机中表示已完成
			return 2;
		}else if(state==1){//启动充电中
			return 1;
		}else if(state==2){
			return 0;
		}
		return state;
	}
	//0 枪已归位   1:未连接    2：已连接
	public  String gunState(int state){
		if(state==0){
			return "枪已归位";
		}else if(state==1){//启动充电中
			return "未连接";
		}else if(state==2){
			return "已连接";
		}
		return state+"";
	}
	
	public  String chargState(int state){
		if(state==0){//待机中表示已完成
			return "待机中";
		}else if(state==1){//启动充电中
			return "启动充电中";
		}else if(state==2){
			return "充电中";
		}else if(state==3){
			return "禁止充电";
		}
		return state+"";
	}
   
   public  String state(int b){
	   if(b==0){
		   return "空闲";
	   }
	   if(b==1){
		   return "连接中";
	   }
	   if(b==2){
		   return "充电中";
	   }
	   if(b==3){
		   return "充电完成";
	   }
	   if(b==4){
		   return "被预约";
	   }
	   if(b==5){
		   return "排队中";
	   }
	   
	return "";
   }
   
   
   
   public Date parseDate(String time){
	   Date date = new Date();
	   SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	   try {
		   date = sf.parse(time);
	} catch (Exception e) {
		e.printStackTrace();
	}
	   return date;
   }
   
   
   public String bl2(double d){
	   BigDecimal bd = new BigDecimal(d);
       bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
       return bd.toString();
   }
   
   
   public static void main(String[] args) throws Exception{
	   /*String time = "2019-5-05 16:24:45";
	   SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	   Date date = sf.parse(time);
	   String s = sf.format(date);
	   System.out.println(s);*/
	  /* double d = 1.2;
	   BigDecimal bd = new BigDecimal(d);
       bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
       System.out.println(bd.toString());
       
       float f = Float.intBitsToFloat(Integer.parseInt("3f666666",16));
       System.out.println(f);
       String s = Integer.toHexString(Float.floatToIntBits(1.5f));
       System.out.println(s);
       
       float w = 0.9f;
       String hex = Integer.toHexString(Float.floatToIntBits(w));
       System.out.println(".........."+hex);
       String hex8 = HexUtil.befor0(hex, 8);
       System.out.println("----"+hex8);
       String fl = HexUtil.hexHighLow(hex8);
       System.out.println("===="+fl);
       
       String ss = fl.substring(0, 8);
       System.out.println(ss);
       
       
       BigDecimal dd = new BigDecimal(9.86);
       System.out.println(dd.shortValue());
       
       long l = Long.valueOf("0000000425319387", 16);
       System.out.println(l);*/
	  /* BigDecimal bd = new BigDecimal(150.005);
       bd = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
       System.out.println(bd);
       int f = (int)(1.36*100000);
       
       String hex = Integer.toHexString(59000);
       String hex8 = HexUtil.befor0(hex, 8);
       System.out.println(hex8);
       
       int i = 3780;
       System.out.println((double)i/10);*/
   }
   
   
   public void insertAndUpdate(String deviceNo,int qh,String warnSpot,int warnDesc){
	   if(warnDesc == 0){//该告警点正常
		   CdzWarn warn = new CdzWarn();
		   warn.setStakeCode(deviceNo);
		   warn.setGunCode(qh+"");
		   warn.setWarnSpot(warnSpot);
		   warn.setStartTime(new Date());
		   List<CdzWarn> list = cdzWarnService.selectCdzWarn(warn);
		   if(CollectionUtil.isNotEmpty(list)){
			   Date endTime = list.get(0).getEndTime();
 			   Date startTime = list.get(0).getStartTime();
 			   if(endTime==null){//没有结束时间，需要更新
 				   //存在一条这样的告警信息
 				   String id = list.get(0).getId();
 				   CdzWarn w = new CdzWarn();
 				   w.setId(id);
 				   endTime = new Date();
 				   long time = (endTime.getTime()-startTime.getTime())/1000;
 				   w.setUpdateTime(endTime);
 				   w.setEndTime(endTime);
 				   w.setWarnTime(time+"");
 				   w.setIsEffect("1");
 				   cdzWarnService.updateByPrimaryKey(w);
 			   }
		   }
	   }else{
		   CdzWarn warn = new CdzWarn();
		   warn.setStakeCode(deviceNo+"");
		   warn.setGunCode(qh+"");
		   warn.setWarnSpot(warnSpot);
		   warn.setWarnDesc(warnDesc+"");
		   List<CdzWarn> list = cdzWarnService.selectCdzWarn(warn);
		   if(CollectionUtil.isNotEmpty(list)){
			   Date endTime = list.get(0).getEndTime();
			   if(endTime != null){//查询出的记录是已恢复告警的，本次需要再新增一条告警记录
				   CdzWarn cdzWarn = new CdzWarn();
				   cdzWarn.setId(IdGenerator.generateId());
				   cdzWarn.setStakeCode(deviceNo+"");
				   cdzWarn.setGunCode(qh+"");
				   cdzWarn.setWarnSpot(warnSpot);
				   cdzWarn.setWarnDesc(warnDesc+"");
				   cdzWarn.setStartTime(new Date());
				   cdzWarn.setCreateTime(new Date());
				   cdzWarnService.insert(cdzWarn);
			   }
		   }else{
			   //数据为空
			   if(warnDesc!=0){//非正常插入一条记录
				   CdzWarn cdzWarn = new CdzWarn();
				   cdzWarn.setId(IdGenerator.generateId());
				   cdzWarn.setStakeCode(deviceNo+"");
				   cdzWarn.setGunCode(qh+"");
				   cdzWarn.setWarnSpot(warnSpot);
				   cdzWarn.setWarnDesc(warnDesc+"");
				   cdzWarn.setStartTime(new Date());
				   cdzWarn.setCreateTime(new Date());
				   cdzWarnService.insert(cdzWarn);
			   }
		   }
	   }
	   
   }
   
   
   public  long secondBetween(Date smdate, Date bdate) throws Exception {
       Calendar cal = Calendar.getInstance();
       cal.setTime(smdate);
       long time1 = cal.getTimeInMillis();
       cal.setTime(bdate);
       long time2 = cal.getTimeInMillis();
       long between_seconds = (time2 - time1) / (1000);
       return between_seconds;
   }
   
   
   
  
   

}
